import type { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios'
import { message } from 'antd'
import axios from 'axios'
import axiosRetry from 'axios-retry'

// 可配置的重试错误码
const RETRY_WHITELIST = new Set(['ECONNABORTED', undefined, 0])

// 创建 axios 实例
const serviceAxios: AxiosInstance = axios.create({
    baseURL: 'http://localhost:3000', // 建议改为 import.meta.env.VITE_API_BASE_URL 等配置方式
    timeout: 15000,
    withCredentials: false,
    headers: {
        'Content-Type': 'application/json;charset=utf-8',
    },
    validateStatus: () => true, // 所有状态码都走到响应拦截器
})

// 自动重试配置
axiosRetry(serviceAxios, {
    retries: 2,
    shouldResetTimeout: true,
    retryDelay: retryCount => retryCount * 10000,
    retryCondition: (error) => {
        const { code, message } = error
        return RETRY_WHITELIST.has(code as string) || message?.includes('timeout')
    },
})

// 请求拦截器
serviceAxios.interceptors.request.use(
    (config: InternalAxiosRequestConfig) => {
        if (import.meta.env.MODE !== 'production') {
            console.log('请求拦截器:', config)
        }
        // 可以在此加入 token 等公共逻辑
        return config
    },
    (error: AxiosError) => {
        console.error('请求拦截器错误:', error)
        return Promise.reject(error)
    },
)

// 响应拦截器
serviceAxios.interceptors.response.use(
    (response: AxiosResponse) => {
        const { status, data } = response
        const { message: msg } = data ?? {}

        if ([200, 201].includes(status)) {
            return data // 直接返回 data，调用方更方便
        }

        if (data?.message) {
            message.error(data.message)
        }
        else if (Array.isArray(msg)) {
            message.error(msg.join(','))
        }
        else if (typeof msg === 'string') {
            message.error(msg)
        }
        else {
            message.error('请求出错')
        }

        return Promise.reject(data)
    },
    (error: AxiosError) => {
        const errorMsg = error.message || '网络异常，请稍后重试'
        message.error(errorMsg)
        return Promise.reject(error)
    },
)

// 封装请求函数
function createRequest(service: AxiosInstance) {
    return function <T = any>(config: AxiosRequestConfig): Promise<T> {
        return service(config)
    }
}

export default createRequest(serviceAxios)
